package com.example.core;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author liheng
 * @ClassName Pailie
 * @Description 参考
 * https://zhuanlan.zhihu.com/p/108033147?from_voters_page=true
 * @date 2021-07-24 13:33
 */
public class Pailie {
    /**
     * 总结下规律，结果为N个字的组合，需要N-1个flatMap
     *
     * @param list 待排列组合字符集合
     * @return 排列组合后的字符串集合
     */
    public static List<String> streamPailie(List<String> list) {
        Stream<String> stream = list.stream();
        stream = stream
                .flatMap(str -> list.stream().map(str::concat))
                .flatMap(str -> list.stream().map(str::concat))
                .flatMap(str -> list.stream().map(str::concat));
        return stream.collect(Collectors.toList());

    }

    /**
     * 排列组合（字符重复排列）<br>
     * 内存占用：需注意结果集大小对内存的占用（list:10位，length:8，结果集:[10 ^ 8 = 100000000]，内存占用:约7G）
     *
     * @param list   待排列组合字符集合
     * @param length 排列组合生成的字符串长度
     * @return 指定长度的排列组合后的字符串集合
     * @author liheng
     */
    public static List<String> streamPailie(List<String> list, int length) {
        Stream<String> stream = list.stream();
        for (int n = 1; n < length; n++) {
            stream = stream.flatMap(str -> list.stream().map(Tools.unicode2String(str)::concat));
        }
        return stream.collect(Collectors.toList());
    }

    /**
     * 排列组合(字符不重复排列)<br>
     * 内存占用：需注意结果集大小对内存的占用（list:10位，length:8，结果集:[10! / (10-8)! = 1814400]）
     *
     * @param list   待排列组合字符集合(忽略重复字符)
     * @param length 排列组合生成长度
     * @return 指定长度的排列组合后的字符串集合
     * @author liheng
     */
    public static List<String> streamPailieDistinct(List<String> list, int length) {
        Stream<String> stream = list.stream().distinct();
        for (int n = 1; n < length; n++) {
            stream = stream.flatMap(str -> list.stream()
                    .filter(temp -> !str.contains(temp))
                    .map(str::concat));
        }
        return stream.collect(Collectors.toList());
    }



}
